home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Sprite 1984 - 1993
/
Sprite 1984 - 1993.iso
/
man
/
cmds.fmt
/
rpcgen.man
< prev
next >
Wrap
Text File
|
1989-12-30
|
16KB
|
463 lines
RPCGEN User Commands RPCGEN
NNAAMMEE
rpcgen - an RPC protocol compiler
SSYYNNOOPPSSIISS
rrppccggeenn --hh [[--oo _o_u_t_f_i_l_e]] [[_i_n_p_u_t_f_i_l_e]]
rrppccggeenn --cc [[--oo _o_u_t_f_i_l_e]] [[_i_n_f_i_l_e]]
rrppccggeenn _i_n_f_i_l_e
rrppccggeenn [[--ss _t_r_a_n_s_p_o_r_t]]** [[--oo _o_u_t_f_i_l_e] [[_i_n_f_i_l_e]]
DDEESSCCRRIIPPTTIIOONN
_r_p_c_g_e_n is a tool that generates CC code to implement an RPC
protocol. The input to _r_p_c_g_e_n is a language with striking
similarity to CC known as RPCL (Remote Procedure Call
Language). _r_p_c_g_e_n operates in four modes. The first mode
is used to convert RPCL definitions into CC definitions for
use as a header file. The second mode compiles the XDR rou-
tines required to serialize the protocol described by RPCL.
The third mode compiles both, leaving the header file in a
file named _i_n_f_i_l_e with a ..hh extension and the XDR routines
in _i_n_f_i_l_e with a ..cc extension. The fourth mode is used to
compile an RPC server skeleton, so that all you have to do
is write local procedures that know nothing about RPC in
order to implement an RPC server.
The input may contain CC-style comments and preprocessor
directives. Comments are ignored, while the directives are
simply stuffed uninterpreted in the output header file.
You can customize some of your XDR routines by leaving those
data types undefined. For every data type that is unde-
fined, _r_p_c_g_e_n will assume that there exists a routine with
the name `xdr_' prepended to the name of the undefined type.
OOPPTTIIOONNSS
--cc Compile XDR routines.
--hh Compile CC data-definitions (a header file)
--oo _o_u_t_f_i_l_e
Specify the name of the output file. If none is speci-
fied, standard output is used (--cc, --hh and --ss modes
only).
--ss _t_r_a_n_s_p_o_r_t
Compile a server, using the the given transport. The
supported transports are uuddpp and ttccpp. This option may
be invoked more than once so as to compile a server
that serves multiple transports.
UUSSAAGGEE
Sprite v1.0 11 March 1986 1
RPCGEN User Commands RPCGEN
RRPPCCLL SSyynnttaaxx SSuummmmaarryy
This summary of RPCL syntax, which is used for _r_p_c_g_e_n input,
is intended more for aiding comprehension than as an exact
statement of the language.
PPrriimmiittiivvee DDaattaa TTyyppeess
[ uunnssiiggnneedd ] cchhaarr
[ uunnssiiggnneedd ] sshhoorrtt
[ uunnssiiggnneedd ] iinntt
[ uunnssiiggnneedd ] lloonngg
uunnssiiggnneedd
ffllooaatt
ddoouubbllee
vvooiidd
bbooooll
Except for the added boolean data-type bbooooll, RPCL is identi-
cal to CC. _r_p_c_g_e_n converts bbooooll declarations to iinntt declara-
tions in the output header file (literally it is converted
to a bbooooll__tt, which has been ##ddeeffiinnee'd to be an iinntt). Also,
vvooiidd declarations may appear only inside of uunniioonn and pprroo--
ggrraamm definitions. For those averse to typing the prefix
uunnssiiggnneedd, the abbreviations uu__cchhaarr, uu__sshhoorrtt, uu__iinntt and
uu__lloonngg are available.
DDeeccllaarraattiioonnss
RPCL allows only three kinds of declarations:
_d_e_c_l_a_r_a_t_i_o_n:
_s_i_m_p_l_e-_d_e_c_l_a_r_a_t_i_o_n
_p_o_i_n_t_e_r-_d_e_c_l_a_r_a_t_i_o_n
_v_e_c_t_o_r-_d_e_c_l_a_r_a_t_i_o_n
_s_i_m_p_l_e-_d_e_c_l_a_r_a_t_i_o_n:
_t_y_p_e-_n_a_m_e _o_b_j_e_c_t-_i_d_e_n_t
_p_o_i_n_t_e_r-_d_e_c_l_a_r_a_t_i_o_n:
_t_y_p_e-_n_a_m_e **_o_b_j_e_c_t-_i_d_e_n_t
_v_e_c_t_o_r-_d_e_c_l_a_r_a_t_i_o_n:
_t_y_p_e-_n_a_m_e _o_b_j_e_c_t-_i_d_e_n_t[[_s_i_z_e]]
(_s_i_z_e can be either an integer or a symbolic constant)
RPCL declarations contain both limitations and extensions
with respect to CC. The limitations are that you cannot
declare multidimensional arrays or pointers-to-pointers in-
line (You can still declare them though, using ttyyppeeddeeff).
There are two extensions:
Opaque data is declared as a vector as follows:
ooppaaqquuee _o_b_j_e_c_t-_i_d_e_n_t [[ _s_i_z_e ]]
Sprite v1.0 11 March 1986 2
RPCGEN User Commands RPCGEN
In the protocol, this results in an object of _s_i_z_e
bytes. Note that this is _n_o_t the same as a declaration
of _s_i_z_e characters, since XDR characters are 32-bits.
Opaque declarations are compiled in the output header
file into character array declarations of _s_i_z_e bytes.
Strings are special and are declared as a vector
declaration:
ssttrriinngg _o_b_j_e_c_t-_i_d_e_n_t [[ _m_a_x-_s_i_z_e ]]
If _m_a_x-_s_i_z_e is unspecified, then there is essentially
no limit to the maximum length of the string. String
declarations get compiled into the following:
char *_o_b_j_e_c_t-_i_d_e_n_t
TTyyppee DDeeffiinniittiioonnss
The only way to generate an XDR routine is to define a type.
For every type _z_e_t_y_p_e you define, there is a corresponding
XDR routine named _x_d_r__z_e_t_y_p_e.
There are six ways to define a type:
_t_y_p_e-_d_e_f_i_n_i_t_i_o_n:
_t_y_p_e_d_e_f
_e_n_u_m_e_r_a_t_i_o_n-_d_e_f
_s_t_r_u_c_t_u_r_e-_d_e_f
_v_a_r_i_a_b_l_e-_l_e_n_g_t_h-_a_r_r_a_y-_d_e_f
_d_i_s_c_r_i_m_i_n_a_t_e_d-_u_n_i_o_n-_d_e_f
_p_r_o_g_r_a_m-_d_e_f
The first three are very similar to their CC namesakes. CC
does not have a formal type mechanism to define variable-
length arrays and XDR unions are quite different from their
CC counterparts. Program definitions are not really type
definitions, but they are useful nonetheless.
You may not nest XDR definitions. For example, the follow-
ing will cause _r_p_c_g_e_n to choke:
struct dontdoit {
struct ididit {
int oops;
} sorry;
enum ididitagain { OOPS, WHOOPS } iapologize;
};
Typedefs
An XDR ttyyppeeddeeff looks as follows:
_t_y_p_e_d_e_f:
ttyyppeeddeeff _d_e_c_l_a_r_a_t_i_o_n ;;
Sprite v1.0 11 March 1986 3
RPCGEN User Commands RPCGEN
The _o_b_j_e_c_t-_i_d_e_n_t part of _d_e_c_l_a_r_a_t_i_o_n is the name of the new
type, whereas the _t_y_p_e-_n_a_m_e part is the name of the type
from which it is derived.
_E_n_u_m_e_r_a_t_i_o_n _T_y_p_e_s
The syntax is:
_e_n_u_m_e_r_a_t_i_o_n-_d_e_f:
eennuumm _e_n_u_m-_i_d_e_n_t {{
_e_n_u_m-_l_i_s_t
}};;
_e_n_u_m-_l_i_s_t:
_e_n_u_m-_s_y_m_b_o_l-_i_d_e_n_t [ == _a_s_s_i_g_n_m_e_n_t ]
_e_n_u_m-_s_y_m_b_o_l-_i_d_e_n_t [ == _a_s_s_i_g_n_m_e_n_t ] ,, _e_n_u_m-_l_i_s_t
(_a_s_s_i_g_n_m_e_n_t may be either an integer or a symbolic constant)
If there is no explicit assignment, then the implicit
assignment is the value of the previous enumeration plus 1.
If not explicitly assigned, the first enumeration receives
the value 0.
_S_t_r_u_c_t_u_r_e_s
_s_t_r_u_c_t_u_r_e-_d_e_f:
ssttrruucctt _s_t_r_u_c_t-_i_d_e_n_t {{
_d_e_c_l_a_r_a_t_i_o_n-_l_i_s_t
}};;
_d_e_c_l_a_r_a_t_i_o_n-_l_i_s_t:
_d_e_c_l_a_r_a_t_i_o_n ;;
_d_e_c_l_a_r_a_t_i_o_n ;; _d_e_c_l_a_r_a_t_i_o_n-_l_i_s_t
_V_a_r_i_a_b_l_e-_L_e_n_g_t_h _A_r_r_a_y_s
_v_a_r_i_a_b_l_e-_l_e_n_g_t_h-_a_r_r_a_y-_d_e_f:
aarrrraayy _a_r_r_a_y-_i_d_e_n_t {{
uunnssiiggnneedd _l_e_n_g_t_h-_i_d_e_n_t_i_f_e_r ;;
_v_e_c_t_o_r-_d_e_c_l_a_r_a_t_i_o_n ;;
}};;
A variable length array definition looks much like a struc-
ture definition. Here's an example:
array mp_int {
unsigned len;
short val[MAX_MP_LENGTH];
};
This is compiled into:
struct mp_int {
unsigned len;
short *val;
};
typedef struct mp_int mp_int;
Sprite v1.0 11 March 1986 4
RPCGEN User Commands RPCGEN
_D_i_s_r_i_m_i_n_a_t_e_d _U_n_i_o_n_s
_d_i_s_c_r_i_m_i_n_a_t_e_d-_u_n_i_o_n-_d_e_f:
uunniioonn _u_n_i_o_n-_i_d_e_n_t sswwiittcchh (( _d_i_s_c_r_i_m_i_n_a_n_t-_d_e_c_l_a_r_a_t_i_o_n )) {{
_c_a_s_e-_l_i_s_t
[ ddeeffaauulltt :: _d_e_c_l_a_r_a_t_i_o_n ;; ]
}};;
_c_a_s_e-_l_i_s_t:
ccaassee _c_a_s_e-_i_d_e_n_t :: _d_e_c_l_a_r_a_t_i_o_n ;;
ccaassee _c_a_s_e-_i_d_e_n_t :: _d_e_c_l_a_r_a_t_i_o_n ;; _c_a_s_e-_l_i_s_t
_d_i_s_c_r_i_m_i_n_a_n_t-_d_e_c_l_a_r_a_t_i_o_n:
_d_e_c_l_a_r_a_t_i_o_n
The union definition looks like a cross between a C-union
and a C-switch. An example:
union net_object switch (net_kind kind) {
case MACHINE:
struct sockaddr_in sin;
case USER:
int uid;
default:
string whatisit;
};
Compiles into:
struct net_object {
net_kind kind;
union {
struct sockaddr_in sin;
int uid;
char *whatisit;
} net_object;
};
typedef struct net_object net_object;
Note that the name of the union component of the output
struct is the same as the name of the type itself.
_P_r_o_g_r_a_m _D_e_f_i_n_i_t_i_o_n_s
_p_r_o_g_r_a_m-_d_e_f:
pprrooggrraamm _p_r_o_g_r_a_m-_i_d_e_n_t {{
_v_e_r_s_i_o_n-_l_i_s_t
}} == _p_r_o_g_r_a_m-_n_u_m_b_e_r ;;
_v_e_r_s_i_o_n-_l_i_s_t:
_v_e_r_s_i_o_n
_v_e_r_s_i_o_n _v_e_r_s_i_o_n-_l_i_s_t
_v_e_r_s_i_o_n:
vveerrssiioonn _v_e_r_s_i_o_n-_i_d_e_n_t {{
_p_r_o_c_e_d_u_r_e-_l_i_s_t
}} == _v_e_r_s_i_o_n-_n_u_m_b_e_r ;;
_p_r_o_c_e_d_u_r_e-_l_i_s_t:
_p_r_o_c_e_d_u_r_e-_d_e_c_l_a_r_a_t_i_o_n
Sprite v1.0 11 March 1986 5
RPCGEN User Commands RPCGEN
_p_r_o_c_e_d_u_r_e-_d_e_c_l_a_r_a_t_i_o_n _p_r_o_c_e_d_u_r_e-_l_i_s_t
_p_r_o_c_e_d_u_r_e-_d_e_c_l_a_r_a_t_i_o_n:
_t_y_p_e-_n_a_m_e _p_r_o_c_e_d_u_r_e-_i_d_e_n_t (( _t_y_p_e-_n_a_m_e )) == _p_r_o_c_e_d_u_r_e-
_n_u_m_b_e_r ;;
Program definitions look like nothing you've ever seen
before, so we turn to an example to explain them. Suppose
you wanted to create server that could get or set the date.
It's declaration might look like this:
program DATE_PROG {
version DATE_VERS {
date DATE_GET(timezone) = 1;
void DATE_SET(date) = 2; /* Greenwich mean time */
} = 1;
} = 100;
In the header file, this compiles into the following:
#define DATE_PROG 100
#define DATE_VERS 1
#define DATE_GET 1
#define DATE_SET 2
These ddeeffiinnee's are intended for use by the client program to
reference the remote procedures.
If you are using _r_p_c_g_e_n to compile your server, then there
are some important things for you to know. The server inter-
faces to your local procedures by expecting a CC function
with the same name as that in the program definition, but in
all lower-case letters and followed by the version number.
Here is the local procedure that implements DATE_GET:
date * /* always returns a pointer to the results */
date_get_1(tz)
timezone *tz; /* always takes a a pointer to the arguments */
{
static date d; /* must be static! */
/*
* figure out the date
* and store it in d
*/
return(&d);
}
The name of the routine is the same as the ##ddeeffiinnee'd name,
but in all lower case letters and followed by the version
number. XDR will recursively free the argument after getting
the results from your local procedure, so you should copy
from the argument any data that you will need between calls.
However, XDR neither allocates nor frees your results. You
must take care of their storage yourself.
Sprite v1.0 11 March 1986 6
RPCGEN User Commands RPCGEN
MMaakkee IInnffeerreennccee RRuulleess FFoorr CCoommppiilliinngg XXDDRR HHeeaaddeerrss
It is possible to set up suffix transformation rules in
_m_a_k_e(1) for compiling XDR routines and header files. The
convention is that RPCL protocol files have the extension
..xx. The _m_a_k_e rules to do this are:
.SUFFIXES: .x
.x.c:
rpcgen -c $< -o $@
.x.h:
rpcgen -h $< -o $@
SSEEEE AALLSSOO
_R_e_m_o_t_e _P_r_o_c_e_d_u_r_e _C_a_l_l: _P_r_o_g_r_a_m_m_i_n_g _G_u_i_d_e and _E_x_t_e_r_n_a_l _D_a_t_a
_R_e_p_r_e_s_e_n_t_a_t_i_o_n: _P_r_o_t_o_c_o_l _S_p_e_c_i_f_i_c_a_t_i_o_n in _N_e_t_w_o_r_k_i_n_g _o_n _t_h_e
_S_u_n _W_o_r_k_s_t_a_t_i_o_n
BBUUGGSS
Name clashes can occur when using program definitions, since
the apparent scoping does not really apply. Most of these
can be avoided by giving unique names for programs, ver-
sions, procedures and types.
Sprite v1.0 11 March 1986 7